package com.itmck.controller;

import com.itmck.component.ApiResultResponse;
import com.itmck.config.ShiroSessionListener;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.DefaultSessionKey;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.crazycake.shiro.RedisCacheManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.HashMap;
import java.util.Map;

@RestController
public class ShiroController {

    @Resource
    private DefaultWebSessionManager sessionManager;

    @Resource
    private RedisCacheManager redisCacheManager;


    @Resource
    private ShiroSessionListener sessionListener;

    @GetMapping("/login")
    public ApiResultResponse<String> login(String username, String pwd) {
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(username, pwd);
        subject.login(token);

        Cache<String, Deque<Serializable>> cache = this.redisCacheManager.getCache("kickout-session");
        Deque<Serializable> deque = cache.get(username);
        if (deque == null) {
            deque = new ArrayDeque<>();
        }

        Session session = subject.getSession();
        if (!deque.contains(session.getId())) {
            deque.add(session.getId());
            cache.put(username, deque);
        }

        while (1 < deque.size()) {
            Serializable serializable = deque.removeFirst();
            if (!serializable.equals(session.getId())) {
                Session kickoutSession = this.sessionManager.getSession(new DefaultSessionKey(serializable));
                kickoutSession.setAttribute("kickout", true);
                kickoutSession.setAttribute("kickoutMsg", "让人踢了");
                cache.put(username, deque);
            }
        }
        return ApiResultResponse.ok("登录成功");
    }


    @GetMapping("/logout")
    public String logout() {
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return "退出登录";
    }

    @GetMapping("/sum")
    public String sum() {

        return "在线人数："+sessionListener.getSessionCount();
    }

    @GetMapping("/unAuthen")
    public String unauth() {

        return "未授权没有访问权限";
    }

    @GetMapping("/static/testM1")
    public Map<String, Object> testM1() {
        Map<String, Object> map = new HashMap<>();
        map.put("field1", "value1");
        return map;
    }

    @GetMapping("/bus/testM2")
    public String testM2() {

        return "testM2";
    }

    @GetMapping("/bus/testM3")
    public String testM3() {
        return "testM3";
    }

    @GetMapping("/bus/testM4")
    @RequiresPermissions("test41")
    public String testM4() {
        return "testM4";
    }
}
